﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.CodeDom.Compiler;
using System.IO;

namespace Lilium.T4.Hosting
{
    [Serializable]
    public class T4CompilerException : Exception
    {
        public T4CompilerException(string templateFile, string generatedClassDefinition, IEnumerable<CompilerError> compilerErrors)
            : base(FormatErrorMessage(templateFile, compilerErrors))
        {
            if (compilerErrors == null) throw new ArgumentNullException("compilerErrors");

            CompilerErrors = compilerErrors.ToArray();
            GeneratedClassDefinition = generatedClassDefinition;
            TemplateFile = templateFile;
        }

        #region public IEnumerable<CompilerError> CompilerErrors

        public IEnumerable<CompilerError> CompilerErrors
        {
            get
            {
                return (IEnumerable<CompilerError>)this.Data["CompilerErrors"];
            }
            private set
            {
                this.Data["CompilerErrors"] = value;
            }
        }

        #endregion

        #region public string GeneratedClassDefinition

        public string GeneratedClassDefinition
        {
            get
            {
                return (string)this.Data["GeneratedClassDefinition"];
            }
            private set
            {
                this.Data["GeneratedClassDefinition"] = value;
            }
        }

        #endregion

        #region public string TemplateFile

        private string m_TemplateFile;

        public string TemplateFile
        {
            get
            {
                return (string)this.Data["TemplateFile"];
            }
            private set
            {
                this.Data["TemplateFile"] = value;
            }
        }

        #endregion



        private static string FormatErrorMessage(string templateFile, IEnumerable<CompilerError> compilerErrors)
        {
            if (compilerErrors == null) throw new ArgumentNullException("compilerErrors");

            var sb = new StringBuilder();
            sb.AppendLine(string.Format("Error compiling {0} template.", Path.GetFileName(templateFile)));

            foreach (var error in compilerErrors)
                sb.AppendLine(string.Format("{0} {1} {2}:{3} {4} {5}", error.Line, Path.GetFileName(error.FileName), error.Line, error.Column, error.IsWarning ? "Warning" : "Error", error.ErrorText));

            return sb.ToString();
        }
    }
}
